package com.ourhours.message.rpc.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.ourhours.global.response.ApiResponse;
import com.ourhours.global.response.ApiResponseBuilder;
import com.ourhours.message.constant.ConstantMQ;
import com.ourhours.message.api.EmailRpcService;
import com.ourhours.message.domain.EmailSend;
import com.ourhours.message.domain.Supplier;
import com.ourhours.message.dto.EmailDto;
import com.ourhours.message.enums.ApiResponseCode;
import com.ourhours.message.enums.MessageTypeEnum;
import com.ourhours.message.exception.MessageException;
import com.ourhours.message.request.EmailRequest;
import com.ourhours.message.service.EmailSendService;
import com.ourhours.message.service.wrapper.SmsWrapper;
import com.ourhours.message.service.wrapper.SupplierWrapper;
import com.ourhours.redismq.Message;
import com.ourhours.redismq.RedisMQMessageSender;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.Date;

@Service("emailRpcService")
@Slf4j
public class EmailRpcServiceImpl implements EmailRpcService {

    @Autowired
    RedisMQMessageSender messageSender;

    @Autowired
    EmailSendService emailSendService;

    @Autowired
    SupplierWrapper supplierWrapper;

    @Autowired
    JmsTemplate jmsTemplate;

    @Autowired
    SmsWrapper smsWrapper;

    @Override
    public ApiResponse<Boolean> sendEmail(EmailRequest request) {
        try {
            Assert.notNull(request, "入参格式不对！");
            Assert.notNull(request.getTitle(), "入参title不能为空！");
            Assert.notNull(request.getContent(), "入参content不能为空！");
            Assert.notNull(request.getVendorId(), "入参vendorId不能为空！");
            Assert.notNull(request.getToAddresses(), "入参toAddress不能为空！");
        } catch (Exception e) {
            log.error("==>邮件发送入参错误!入参:{}.错误:{}.", request, e.getMessage());
            return ApiResponseBuilder.buildError(ApiResponseCode.ARG_ERROR.getCode(), e.getMessage(), false);
        }
        EmailDto dto = new EmailDto();
        dto.setTitle(request.getTitle());
        dto.setContent(request.getContent());
        dto.setToAddresses(request.getToAddresses());
        dto.setVendorId(request.getVendorId());
        dto.setAttachmentUrls(request.getAttachmentUrls());
        Supplier supplier = supplierWrapper.findSupplierWithCache(dto.getVendorId(), MessageTypeEnum.EMAIL.getCode());
        if (supplier == null || supplier.getId() == null) {
            log.error("==>邮件发送错误!获取邮件服务商信息失败.入参:{}.", request);
            return ApiResponseBuilder.buildError(ApiResponseCode.ERROR.getCode(), "获取邮件服务商信息失败", false);
        }
        // 先保存数据库，但如果连保存数据库都失败，后续也不改状态了。
        try {
            this.saveEmail(dto, supplier);
            Long redisResult = messageSender.put(new Message(ConstantMQ.emailMQ, JSON.toJSONString(dto)));
            // 存redis失败
            if (redisResult == null){
                smsWrapper.smsAlarmInfo(request.getVendorId());
                //直接发
                try {
                    emailSendService.sendEmail(dto);
                    emailSendService.setEmailSendStatus(dto.getId(), 1, null, null);
                    return ApiResponseBuilder.buildSuccess(true);
                } catch (Exception ee) {
                    emailSendService.setEmailSendStatus(dto.getId(), -1, ApiResponseCode.ERROR.getCode(), ee.getMessage());
                    return ApiResponseBuilder.buildError(ApiResponseCode.ERROR.getCode(), ee.getMessage(), false);
                }
            }
            return ApiResponseBuilder.buildSuccess(true);
        }
        catch (MessageException e){
            log.error("==>邮件发送错误!入参:{}.错误:{}.", request, e.getMessage());
            return ApiResponseBuilder.buildError(e.getCode(), e.getMsg(), false);
        }
        catch (Exception e) {
            log.error("==>邮件发送错误!入参:{}.错误:{}.", request, e.getMessage());
            return ApiResponseBuilder.buildError(ApiResponseCode.ERROR.getCode(), e.getMessage(), false);
        }
    }

    private void saveEmail(EmailDto dto, Supplier supplier) {
        try {
            EmailSend entity = new EmailSend();
            boolean reject = false;//每日超限拒绝
            // 邮件不做限制，如以后开通每日限制，再设置成true
            boolean isCheckLimitSendCount = false;
            if(!isCheckLimitSendCount) {
                EntityWrapper wrapper = new EntityWrapper();
                wrapper.eq("supplier_id", supplier.getId());
                wrapper.eq("deleted", 0);
                wrapper.eq("target", dto.getToAddresses());
                wrapper.lt("status", 2);
                Integer existsCount = emailSendService.selectCount(wrapper);
                Integer limitCount = supplier.getTimesLimitPerDay();
                if (!(limitCount == null || limitCount == 0 || existsCount < limitCount)) {
                    reject = true;
                    entity.setStatus(reject ? 2 : 0);
                }
            }
            entity.setContent(dto.getContent());
            entity.setTitle(dto.getTitle());
            entity.setVendorId(dto.getVendorId());
            entity.setSupplierId(supplier.getId());
            entity.setTarget(dto.getToAddresses());
            entity.setNetworkAttachment(dto.getAttachmentUrls());
            entity.setSysVersion(1);
            entity.setCreateTime(new Date());
            entity.setUpdateTime(new Date());
            entity.setCreateUser("MQ");
            entity.setUpdateUser("MQ");
            emailSendService.insertOrUpdate(entity);
            dto.setId(entity.getId());
            if (reject){
                throw new MessageException(ApiResponseCode.BUSINESS_ERROR,"发送次数超限");
            }
        } catch (Exception e) {
            throw new MessageException(ApiResponseCode.ERROR,"初始化发送记录表失败.参数:"+dto+",原因:"+e+"");
        }
    }
}
